/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Portions created by the Initial Developer are
 * Copyright (C) 2012 the Initial Developer.
 * All Rights Reserved.
 *
 * The Original Code is "http://semi-frame.googlecode.com/svn/trenk/".
 *
 * The Initial Developer of the Original Code is the author below.
 */
/**
 * @file TimerMessage.cpp
 * @brief auto generated.
 * @author mornongcloud
 * @date 2012/03/11
 */

#include "semi/CurrentTasks.h"

namespace semi {

std::string CurrentTasks::current_task_file_name = "semi.CurrentTask";

CurrentTasks::CurrentTasks() {
}

CurrentTasks::CurrentTasks(std::string taskId) {
	this->init(taskId);
}

void CurrentTasks::init(std::string taskid) {

	this->taskId = taskid;
	this->index = -1;

	this->mcrnt.init(CurrentTasks::current_task_file_name,
			sizeof(CurrentTasks::CurrentTaskIds));

	CurrentTasks::CurrentTaskIds *mtsk =
			(CurrentTasks::CurrentTaskIds*) this->mcrnt.get();

	for (int idx = 0; this->index < 0 && idx
			< (sizeof(CurrentTasks::CurrentTaskIds)
					/ sizeof(CurrentTasks::CurrentTask)); idx++) {
		CurrentTasks::CurrentTask tsk = mtsk->task[idx];
		if (0 == strncmp(tsk.task_id, (char*) taskid.c_str(), taskid.length())) {
			this->index = idx;
			break;
		}
	}

	for (int idx = 0; this->index < 0 && idx
			< (sizeof(CurrentTasks::CurrentTaskIds)
					/ sizeof(CurrentTasks::CurrentTask)); idx++) {
		CurrentTasks::CurrentTask tsk = mtsk->task[idx];
		if (0 == tsk.task_id[0]) {
			this->index = idx;
			break;
		}
	}

	if (this->index < 0) {
		this->mcrnt.end();
		return;
	}

	memset(mtsk->task[this->index].task_id, 0,
			sizeof(mtsk->task[this->index].task_id));
	strncpy(mtsk->task[this->index].task_id, (char*) this->taskId.c_str(),
			this->taskId.length());

	this->mcrnt.end();
}

CurrentTasks::~CurrentTasks() {
}

void CurrentTasks::setValid(bool val) {

	CurrentTasks::CurrentTaskIds *mtsk =
			(CurrentTasks::CurrentTaskIds*) this->mcrnt.get();

	if (val) {

		//		memset(mtsk->task[this->index].task_id, 0,
		//				sizeof(mtsk->task[this->index].task_id));
		//		strncpy(mtsk->task[this->index].task_id, (char*) this->taskId.c_str(),
		//				this->taskId.length());
		mtsk->task[this->index].valid = '1';
		mtsk->task[this->index].pid = getpid();
		mtsk->task[this->index].ppid = getppid();
	} else {
		// memset(mtsk, 0, sizeof(CurrentTasks::CurrentTask));
		mtsk->task[this->index].valid = '0';
	}

	this->mcrnt.end();

	return;
}

bool CurrentTasks::isValid() {

	CurrentTasks::CurrentTaskIds *mtsk =
			(CurrentTasks::CurrentTaskIds*) this->mcrnt.get(PROT_READ);

	bool ret = ('1' == mtsk->task[this->index].valid);

	this->mcrnt.end();
	mtsk = 0;

	return ret;
}

void CurrentTasks::setChildPid(int pid) {

	CurrentTasks::CurrentTaskIds *mtsk =
			(CurrentTasks::CurrentTaskIds*) this->mcrnt.get();
	mtsk->task[this->index].cpid = pid;
	this->mcrnt.end();
}

void CurrentTasks::removeChildPid() {

	CurrentTasks::CurrentTaskIds *mtsk =
			(CurrentTasks::CurrentTaskIds*) this->mcrnt.get();
	mtsk->task[this->index].cpid = 0;
	this->mcrnt.end();
}

bool CurrentTasks::hasChildPid() {

	CurrentTasks::CurrentTaskIds *mtsk =
			(CurrentTasks::CurrentTaskIds*) this->mcrnt.get(PROT_READ);
	bool ret = (0 < mtsk->task[this->index].cpid);
	this->mcrnt.end();
	return ret;
}

void CurrentTasks::setLastTimestamp(long long tim) {

	CurrentTasks::CurrentTaskIds *mtsk =
			(CurrentTasks::CurrentTaskIds*) this->mcrnt.get();
	mtsk->task[this->index].last = tim;
	this->mcrnt.end();
}

void CurrentTasks::clear() {
	CurrentTasks::CurrentTaskIds* mtsk =
			(CurrentTasks::CurrentTaskIds*) this->mcrnt.get();
	memset(&mtsk->task[this->index], 0, sizeof(CurrentTasks::CurrentTask));
	this->mcrnt.end();
	//	this->mcrnt.terminate();
}

// static
util::Strings CurrentTasks::getCurrentTaskIds() {

	util::Strings ret;
	util::Strings::iterator iter = ret.begin();

	posix::SharedMemory mm(CurrentTasks::current_task_file_name,
			sizeof(CurrentTasks::CurrentTaskIds));

	CurrentTasks::CurrentTaskIds
			*mtsk = (CurrentTasks::CurrentTaskIds*) mm.get(PROT_READ);
	for (int idx = 0; idx < (sizeof(CurrentTasks::CurrentTaskIds)
			/ sizeof(CurrentTasks::CurrentTask)); idx++) {
		CurrentTasks::CurrentTask tsk = mtsk->task[idx];

		std::string tskid(tsk.task_id);
		if ('1' == tsk.valid && 0 < tskid.length()) {
			ret.insert(iter, tskid);
		}
	}
	return ret;
}

// static
std::string CurrentTasks::toString(bool all) {

	posix::SharedMemory mm(CurrentTasks::current_task_file_name,
			sizeof(CurrentTasks::CurrentTaskIds));

	CurrentTasks::CurrentTaskIds
			*mtsk = (CurrentTasks::CurrentTaskIds*) mm.get(PROT_READ);

	std::stringstream ss;
	ss << std::endl << CurrentTasks::current_task_file_name << std::endl;

	int cnt = 0;
	for (int idx = 0; idx < (sizeof(CurrentTasks::CurrentTaskIds)
			/ sizeof(CurrentTasks::CurrentTask)); idx++) {
		CurrentTasks::CurrentTask tsk = mtsk->task[idx];

		if (all || '1' == tsk.valid) {
			ss << CurrentTasks::toStringCurrentTask(&tsk) << std::endl;
			cnt++;
		}
	}

	ss << "    display count:" << cnt << std::endl;
	//    std::cout << ss.str() << std::endl;

	mm.end();

	return ss.str();
}

// private
std::string CurrentTasks::toStringCurrentTask(CurrentTask* crnttsk) {

	std::stringstream ss;

	ss << "    ";
	ss << std::string(crnttsk->task_id) << " valid:" << crnttsk->valid;
	if (0 < crnttsk->last) {
		util::DateUtil du(crnttsk->last);

		ss << " last:";
		if (du.getHour() < 10)
			ss << "0";
		ss << du.getHour() << ":";
		if (du.getMin() < 10)
			ss << "0";
		ss << du.getMin() << " ";
		if (du.getSec() < 10)
			ss << "0";
		ss << du.getSec();
	}
	if (0 < crnttsk->pid) {
		ss << " thread:" << crnttsk->pid;
		if (0 < crnttsk->cpid)
			ss << " child:" << crnttsk->cpid;
		if (0 < crnttsk->ppid)
			ss << " parent:" << crnttsk->ppid;
	}
	return ss.str();
}

}

